const { spawn, execSync } = require('child_process')
const { join } = require('path')
const { writeFileSync, existsSync } = require('fs')
const fs = require('fs')
const path = require('path')
const toml = require('@iarna/toml')

function getConfigPath(frpPath) {
  return path.join(frpPath, 'frpc.toml')
}

function generateTomlObject(config) {
  return {
    common: {
      server_addr: config.server_addr,
      server_port: config.server_port,
      token: config.token,
      log_level: config.log_level,
    },
  }
}

function writeTomlFile(config) {
  const configPath = getConfigPath(config.frp_path)
  let existing = {}

  // 如果存在旧配置，读取保留代理项
  if (fs.existsSync(configPath)) {
    const content = fs.readFileSync(configPath, 'utf-8')
    existing = toml.parse(content)
  }

  const newConfig = generateTomlObject(config)

  // 添加原来的代理配置（非 common 段）
  for (const [key, val] of Object.entries(existing)) {
    if (key !== 'common') {
      newConfig[key] = val
    }
  }

  // 使用 toml.stringify 输出格式正确的 TOML 字符串
  const tomlStr = toml.stringify(newConfig)
  fs.writeFileSync(configPath, tomlStr, 'utf-8')
  return configPath
}

// 用于保存子进程（如果你要后续停止它）
let frpcProcess = null

function runFrpc(config, callback) {
  const exePath = join(config.frp_path, 'frpc.exe')
  const tomlPath = join(config.frp_path, 'frpc.toml')

  if (!existsSync(exePath)) throw new Error('frpc.exe 不存在')
  if (!existsSync(tomlPath)) throw new Error('frpc.toml 不存在')

  const child = spawn(exePath, ['-c', tomlPath], {
    cwd: config.frp_path,
    windowsHide: true,
  })

  frpcProcess = child

  let output = ''

  child.stdout.on('data', data => {
    output += data.toString()
    console.log('[frpc stdout]', data.toString())
  })

  child.stderr.on('data', data => {
    output += data.toString()
    console.error('[frpc stderr]', data.toString())
  })

  child.on('error', err => {
    console.error('[frpc error]', err)
    callback(err)
  })

  // ✅ 启动后立即响应，不等待退出
  setTimeout(() => {
    callback(null, output || 'frpc 已启动')
  }, 500) // 可延迟一点以确保启动有输出
}

function selectFolder() {
  const psCommand = `
    Add-Type -AssemblyName System.Windows.Forms;
    $f = New-Object System.Windows.Forms.FolderBrowserDialog;
    if ($f.ShowDialog() -eq "OK") { Write-Output $f.SelectedPath }
  `
  const result = execSync(`powershell -command "${psCommand}"`, {
    encoding: 'utf-8',
  })
  return result.trim()
}

module.exports = {
  generateTomlObject,
  writeTomlFile,
  runFrpc,
  selectFolder,
}
